package org.xbl.xchain.sdk.tx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bouncycastle.util.encoders.Hex;
import org.xbl.xchain.sdk.amino.Codec;
import org.xbl.xchain.sdk.types.Version;

import java.util.Base64;
import java.util.List;

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class TxInfo {

    private Long height;

    private String txhash;

    private Integer code;

    private String codespace;

    private String rawLog;

    private List<TxLog> logs;

    private StdTx tx;

    private Long gasWanted;

    private Long gasUsed;

    private String timestamp;

    public TxInfo(TxResponse txResponse, String version) {
        this.height = txResponse.getHeight();
        this.txhash = txResponse.getHash();
        byte[] txData = Base64.getDecoder().decode(txResponse.getTx());
        this.tx = Codec.getAmino(version).unmarshalBinaryLengthPrefixed(txData, StdTx.class);
        this.code = txResponse.getTxResult().getCode();
        this.codespace = txResponse.getTxResult().getCodespace();
        this.rawLog = txResponse.getTxResult().getLog();
        this.gasWanted = txResponse.getTxResult().getGasWanted();
        this.gasUsed = txResponse.getTxResult().getGasUsed();
        if (isSuccess()) {
            this.logs = JSON.parseArray(txResponse.getTxResult().getLog(), TxLog.class);
        }
    }

    public Boolean isSuccess() {
        if (code == null) {
            return false;
        }
        return code == 0;
    }

    @Data
    public static class TxLog {
        private Integer msgIndex;
        private String log;
        private List<Event> events;
    }

    @Data
    public static class Event {
        private String type;
        private List<Attribute> attributes;
    }

    @Data
    public static class Attribute {
        private String key;
        private String value;
    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class TxResponse {
        private Integer index;
        @JSONField(name = "tx_result")
        private TxResult txResult;
        private String tx;
        private String hash;
        private Long height;
    }

    @Data
    public static class TxResult {
        private Long gasWanted;

        private Long gasUsed;

        private Integer code;

        private String codespace;

        private String log;

        private String info;

        private List<Event> events;
    }


}
